home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / editors / mjovesrc.zoo / move.c < prev    next >
C/C++ Source or Header  |  1992-04-04  |  5KB  |  301 lines

  1. /***************************************************************************
  2.  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  3.  * is provided to you without charge, and with no warranty.  You may give  *
  4.  * away copies of JOVE, including sources, provided that this notice is    *
  5.  * included in all the files.                                              *
  6.  ***************************************************************************/
  7.  
  8. #include "jove.h"
  9. #include "re.h"
  10. #include "ctype.h"
  11. #include "disp.h"
  12.  
  13. private int    line_pos;
  14.  
  15. void
  16. f_char(n)
  17. register int    n;
  18. {
  19.     if (n < 0) {
  20.         b_char(-n);
  21.         return;
  22.     }
  23.     while (--n >= 0) {
  24.         if (eolp()) {            /* Go to the next Line */
  25.             if (curline->l_next == NULL)
  26.                 break;
  27.             SetLine(curline->l_next);
  28.         } else
  29.             curchar += 1;
  30.     }
  31. }
  32.  
  33. void
  34. b_char(n)
  35. register int    n;
  36. {
  37.     if (n < 0) {
  38.         f_char(-n);
  39.         return;
  40.     }
  41.     while (--n >= 0) {
  42.         if (bolp()) {
  43.             if (curline->l_prev == NULL)
  44.                 break;
  45.             SetLine(curline->l_prev);
  46.             Eol();
  47.         } else
  48.             curchar -= 1;
  49.     }
  50. }
  51.  
  52. void
  53. ForChar()
  54. {
  55.     f_char(arg_value());
  56. }
  57.  
  58. void
  59. BackChar()
  60. {
  61.     b_char(arg_value());
  62. }
  63.  
  64. void
  65. NextLine()
  66. {
  67.     if ((curline == curbuf->b_last) && eolp())
  68.         complain(NullStr);
  69.     line_move(FORWARD, arg_value(), YES);
  70. }
  71.  
  72. void
  73. PrevLine()
  74. {
  75.     if ((curline == curbuf->b_first) && bolp())
  76.         complain(NullStr);
  77.     line_move(BACKWARD, arg_value(), YES);
  78. }
  79.  
  80. /* moves to a different line in DIR; LINE_CMD says whether this is
  81.    being called from NextLine() or PrevLine(), in which case it tries
  82.    to line up the column with the column of the current line */
  83.  
  84. void
  85. line_move(dir, n, line_cmd)
  86. int    dir,
  87.     n;
  88. bool    line_cmd;
  89. {
  90.     Line    *(*proc) ptrproto((Line *, int)) =
  91.         (dir == FORWARD) ? next_line : prev_line;
  92.     Line    *line;
  93.  
  94.     line = (*proc)(curline, n);
  95.     if (line == curline) {
  96.         if (dir == FORWARD)
  97.             Eol();
  98.         else
  99.             Bol();
  100.         return;
  101.     }
  102.  
  103.     if (line_cmd) {
  104.         this_cmd = LINECMD;
  105.         if (last_cmd != LINECMD)
  106.             line_pos = calc_pos(linebuf, curchar);
  107.     }
  108.     SetLine(line);        /* curline is in linebuf now */
  109.     if (line_cmd)
  110.         curchar = how_far(curline, line_pos);
  111. }
  112.  
  113. /* returns what cur_char should be for that position col */
  114.  
  115. int
  116. how_far(line, col)
  117. Line    *line;
  118. int    col;
  119. {
  120.     register char    *lp;
  121.     register int    pos,
  122.             c;
  123.     char    *base;
  124.  
  125.     base = lp = lcontents(line);
  126.     pos = 0;
  127.  
  128.     while (pos < col && (c = (*lp & CHARMASK)) != '\0') {
  129.         if (c == '\t')
  130.             pos += (tabstop - (pos % tabstop));
  131.         else if (jiscntrl(c))
  132.             pos += 2;
  133.         else
  134.             pos += 1;
  135.         lp += 1;
  136.     }
  137.  
  138.     return lp - base;
  139. }
  140.  
  141. void
  142. Bol()
  143. {
  144.     curchar = 0;
  145. }
  146.  
  147. void
  148. Eol()
  149. {
  150.     curchar = length(curline);
  151. }
  152.  
  153. void
  154. Eof()
  155. {
  156.     PushPntp(curbuf->b_last);
  157.     ToLast();
  158. }
  159.  
  160. void
  161. Bof()
  162. {
  163.     PushPntp(curbuf->b_first);
  164.     ToFirst();
  165. }
  166.  
  167. /* Move forward (if dir > 0) or backward (if dir < 0) a sentence.  Deals
  168.    with all the kludgery involved with paragraphs, and moving backwards
  169.    is particularly yucky. */
  170.  
  171. private void
  172. to_sent(dir)
  173. int    dir;
  174. {
  175.     Bufpos    *new,
  176.         old;
  177.  
  178.     DOTsave(&old);
  179.  
  180.     new = dosearch("^[ \t]*$\\|[?.!]", dir, YES);
  181.     if (new == NULL) {
  182.         if (dir == BACKWARD)
  183.             ToFirst();
  184.         else
  185.             ToLast();
  186.         return;
  187.     }
  188.     SetDot(new);
  189.     if (dir < 0) {
  190.         to_word(1);
  191.         if ((old.p_line == curline && old.p_char <= curchar) ||
  192.             (inorder(new->p_line, new->p_char, old.p_line, old.p_char) &&
  193.              inorder(old.p_line, old.p_char, curline, curchar))) {
  194.             SetDot(new);
  195.             to_sent(dir);
  196.         }
  197.         return;        /* We're there? */
  198.     }
  199.     if (blnkp(linebuf)) {
  200.         Bol();
  201.         b_char(1);
  202.         if (old.p_line == curline && old.p_char >= curchar) {
  203.             to_word(1);    /* Oh brother this is painful */
  204.             to_sent(1);
  205.         }
  206.     } else {
  207.         curchar = REbom + 1;    /* Just after the [?.!] */
  208.         if (LookingAt("[\")]  *\\|[\")]$", linebuf, curchar))
  209.             curchar += 1;
  210.         else if (!eolp() && !LookingAt("  *", linebuf, curchar))
  211.             to_sent(dir);
  212.     }
  213. }
  214.  
  215. void
  216. Bos()
  217. {
  218.     register int    num = arg_value();
  219.  
  220.     if (num < 0) {
  221.         negate_arg_value();
  222.         Eos();
  223.         return;
  224.     }
  225.  
  226.     while (--num >= 0) {
  227.         to_sent(-1);
  228.         if (bobp())
  229.             break;
  230.     }
  231. }
  232.  
  233. void
  234. Eos()
  235. {
  236.     register int    num = arg_value();
  237.  
  238.     if (num < 0) {
  239.         negate_arg_value();
  240.         Bos();
  241.         return;
  242.     }
  243.  
  244.     while (--num >= 0) {
  245.         to_sent(1);
  246.         if (eobp())
  247.             break;
  248.     }
  249. }
  250.  
  251. void
  252. f_word(num)
  253. register int    num;
  254. {
  255.     register char    c;
  256.     if (num < 0) {
  257.         b_word(-num);
  258.         return;
  259.     }
  260.     while (--num >= 0) {
  261.         to_word(FORWARD);
  262.         while ((c = linebuf[curchar]) != '\0' && jisword(c))
  263.             curchar += 1;
  264.         if (eobp())
  265.             break;
  266.     }
  267.     this_cmd = 0;    /* Semi kludge to stop some unfavorable behavior */
  268. }
  269.  
  270. void
  271. b_word(num)
  272. register int    num;
  273. {
  274.     register char    c;
  275.  
  276.     if (num < 0) {
  277.         f_word(-num);
  278.         return;
  279.     }
  280.     while (--num >= 0) {
  281.         to_word(BACKWARD);
  282.         while (!bolp() && (c = linebuf[curchar - 1], jisword(c)))
  283.             curchar -= 1;
  284.         if (bobp())
  285.             break;
  286.     }
  287.     this_cmd = 0;
  288. }
  289.  
  290. void
  291. ForWord()
  292. {
  293.     f_word(arg_value());
  294. }
  295.  
  296. void
  297. BackWord()
  298. {
  299.     b_word(arg_value());
  300. }
  301.